package com.bocloud.cmp.service.resource;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.alibaba.fastjson.JSONObject;
import com.bocloud.cmp.dao.CloudServerDao;
import com.bocloud.cmp.dao.CloudVendorDao;
import com.bocloud.cmp.dao.DataStoreDao;
import com.bocloud.cmp.dao.HostPerfDao;
import com.bocloud.cmp.dao.HostSystemDao;
import com.bocloud.cmp.dao.NetworkCardDao;
import com.bocloud.cmp.dao.NetworkDao;
import com.bocloud.cmp.dao.NetworkHostDao;
import com.bocloud.cmp.dao.PortGroupDao;
import com.bocloud.cmp.dao.SnapshotDao;
import com.bocloud.cmp.dao.StoreHostDao;
import com.bocloud.cmp.dao.VdcDao;
import com.bocloud.cmp.dao.utils.MonitorConvert;
import com.bocloud.cmp.driver.providers.intf.HostProvider;
import com.bocloud.cmp.driver.providers.intf.MonitorProvider;
import com.bocloud.cmp.driver.providers.intf.NetworkProvider;
import com.bocloud.cmp.entity.resource.CloudServer;
import com.bocloud.cmp.entity.resource.CloudVendor;
import com.bocloud.cmp.entity.resource.DataStore;
import com.bocloud.cmp.entity.resource.HostSystem;
import com.bocloud.cmp.entity.resource.Network;
import com.bocloud.cmp.entity.resource.NetworkCard;
import com.bocloud.cmp.entity.resource.PortGroup;
import com.bocloud.cmp.entity.resource.Vdc;
import com.bocloud.cmp.enums.VMStatus;
import com.bocloud.cmp.enums.VendorType;
import com.bocloud.cmp.interfaces.resource.HostSystemService;
import com.bocloud.cmp.model.HostOperateModel;
import com.bocloud.cmp.model.HostSystemBean;
import com.bocloud.cmp.model.MonitorCategoryModel;
import com.bocloud.cmp.model.MonitorModel;
import com.bocloud.cmp.model.SwitchModel;
import com.bocloud.cmp.service.model.OperateResult;
import com.bocloud.cmp.service.utils.ResourceEventPublisher;
import com.bocloud.cmp.service.utils.SyncVmwareUtils;
import com.bocloud.common.model.BsmResult;
import com.bocloud.common.model.GridBean;
import com.bocloud.common.model.Param;
import com.bocloud.common.model.Sign;
import com.bocloud.common.model.SimpleBean;
import com.bocloud.common.utils.Common;
import com.bocloud.common.utils.GridHelper;
import com.bocloud.common.utils.JSONTools;
import com.bocloud.common.utils.ListTool;
import com.bocloud.common.utils.MapTools;
import com.bocloud.coordinator.harmony.HarmonyLock;
import com.bocloud.coordinator.harmony.LockFactory;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

@Service("hostSystemService")
public class HostSystemServiceImpl implements HostSystemService {

	private static final Logger logger = LoggerFactory.getLogger(HostSystemServiceImpl.class);
	@Autowired
	private HostSystemDao hostSystemDao;
	@Autowired
	private LockFactory lockFactory;
	@Autowired
	private CloudVendorDao cloudVendorDao;
	@Autowired
	private NetworkCardDao networkCardDao;
	@Autowired
	private NetworkDao networkDao;
	@Autowired
	private VdcDao vdcDao;
	@Autowired
	private CloudServerDao cloudServerDao;
	@Autowired
	private SnapshotDao snapshotDao;
	@Autowired
	private StoreHostDao storeHostDao;
	@Autowired
	private DataStoreDao dataStoreDao;
	@Autowired
	private NetworkHostDao networkHostDao;
	@Autowired
	private PortGroupDao portGroupDao;
	@Autowired
	private NetworkProvider networkProvider;
	@Autowired
	private MonitorProvider monitorProvider;
	@Autowired
	private HostProvider hostProvider;
	@Autowired
	private ResourceEventPublisher resourceEventPublisher;
	@Autowired
	private HostPerfDao perfDao;

	@Override
	public BsmResult list(int page, int rows, List<Param> params, Map<String, String> sorter, Boolean simple) {
		GridBean gridBean = null;
		try {
			if (null == params) {
				params = Lists.newArrayList();
			}
			if (null == sorter) {
				sorter = Maps.newHashMap();
			}
			sorter.put("gmtCreate", Common.ONE);
			int total = this.hostSystemDao.count(params);
			if (simple) {
				List<SimpleBean> beans = this.hostSystemDao.list(params, sorter);
				gridBean = new GridBean(1, 1, total, beans);
			} else {
				List<HostSystem> list = this.hostSystemDao.list(page, rows, params, sorter);
				for (HostSystem hostSystem : list) {
					params.clear();
					params.add(new Param(MapTools.simpleMap("hostId", hostSystem.getId()), Sign.EQ));
					int vmNum = cloudServerDao.count(params);
					params.add(new Param(MapTools.simpleMap("isTemplate", 1), Sign.EQ));
					int templateNum = cloudServerDao.count(params);
					hostSystem.setVmNum(vmNum - templateNum);
					hostSystem.setTemplateNum(templateNum);
				}
				gridBean = GridHelper.getBean(page, rows, total, list);
			}
			return new BsmResult(true, gridBean, "查询成功");
		} catch (Exception e) {
			logger.error("Query host list fail:", e);
			return new BsmResult(false, "查询失败");
		}
	}

	@Override
	public BsmResult create(HostOperateModel model, Long userId) {
		try {
			Long vendorId = model.getVendorId();
			CloudVendor vendor = cloudVendorDao.query(vendorId);
			if (null == vendor) {
				return new BsmResult(false, "获取运供应商失败");
			}
			// 启动一个线程
			new Thread(new Runnable() {
				@Override
				public void run() {
					BsmResult result = hostProvider.create(vendor.getUuid(), null, model);
					String type = vendor.getType();
					String operate = type.toLowerCase() + ".host";
					if (result.isSuccess() && null != result.getData()) {
						try {
							String content = JSONObject.toJSONString(result.getData());
							HostSystem hostSystem = JSONObject.parseObject(content, HostSystem.class);
							switch (VendorType.valueOf(type)) {
							case OPENSTACK:
								break;
							case VMWARE:
								hostSystem.preSave(userId, userId, vendorId, model.getVdcId(), model.getClusterId());
								hostSystemDao.save(hostSystem);
								Long hostId = hostSystem.getId();
								SyncVmwareUtils utils = new SyncVmwareUtils(cloudServerDao, dataStoreDao, hostSystemDao,
										snapshotDao, networkDao, null, storeHostDao, networkCardDao, portGroupDao,
										networkHostDao);
								// 获取数据中心的网络关系
								Map<String, Long> networkMap = Maps.newHashMap();
								Map<String, PortGroup> groupMap = Maps.newHashMap();
								List<Network> oldNetworks = networkDao.listByVdc(hostSystem.getVdcId());
								for (Network network : oldNetworks) {
									networkMap.put(network.getNetworkVal(), network.getId());
									List<PortGroup> groups = portGroupDao.listByNetwork(network.getId());
									for (PortGroup group : groups) {
										groupMap.put(group.getGroupVal(), group);
									}
								}
								// 保存物理网卡
								utils.addCard(vendorId, hostId, userId, "PM", hostSystem.getNetcards(), groupMap);
								// 保存存储
								Map<String, Long> storeMap = new HashMap<>();
								List<DataStore> stores = dataStoreDao.listByVdc(hostSystem.getVdcId());
								for (DataStore store : stores) {
									storeMap.put(store.getStoreVal(), store.getId());
								}
								List<DataStore> dataStores = hostSystem.getDataStores();
								if (null != dataStores) {
									for (DataStore dataStore : dataStores) {
										if (storeMap.containsKey(dataStore.getStoreVal())) {
											continue;
										}
										dataStore.preSave(userId, userId, vendorId, model.getVdcId());
										dataStoreDao.save(dataStore);
										storeMap.put(dataStore.getStoreVal(), dataStore.getId());
									}
								}
								// 宿主机和存储建立关系
								utils.addStore(vendorId, hostId, userId, "PM", hostSystem.getStores(), storeMap);
								// 宿主机和网络的关系
								utils.addNetwork(vendorId, hostId, userId, "PM", hostSystem.getNetworks(), networkMap,
										groupMap);
								// 保存虚拟机
								List<CloudServer> cloudServers = hostSystem.getServers();
								if (!ListTool.isEmpty(cloudServers)) {
									for (CloudServer server : cloudServers) {
										utils.addServerCascade(storeMap, server, vendorId, hostId, userId,
												hostSystem.getPowerState(), networkMap, groupMap);
									}
								}
								break;
							default:
								break;
							}
						} catch (Exception e) {
							logger.error("Create host fail:", e);
							resourceEventPublisher.send(new OperateResult(false, "添加宿主机失败", operate,
									MapTools.simpleMap("vendorId", vendor.getId())));
						}
					}
					resourceEventPublisher.send(new OperateResult(result.isSuccess(), result.getMessage(), operate,
							MapTools.simpleMap("vendorId", vendor.getId())));
				}
			}).start();
			return new BsmResult(true, "添加任务已经下发，正在执行……");
		} catch (Exception e) {
			logger.error("Create host fail:", e);
			return new BsmResult(false, "添加失败");
		}
	}

	@Override
	public BsmResult modify(HostSystemBean bean, Long userId) {
		String path = HostSystem.class.getSimpleName() + "_" + bean.getId();
		HarmonyLock lock = null;
		try {
			lock = lockFactory.getLock(path);
			if (!lock.acquire(path, 10, TimeUnit.SECONDS)) {
				logger.warn("Get harmonyLock time out!");
				return new BsmResult(false, "请求超时");
			}
			HostSystem host = this.hostSystemDao.query(bean.getId());
			if (null == host) {
				logger.warn("HostSystem does not exist!");
				return new BsmResult(false, "数据不存在");
			}
			BeanUtils.copyProperties(bean, host);
			host.setMenderId(userId);
			this.hostSystemDao.update(host);
			return new BsmResult(true, "修改成功");
		} catch (Exception e) {
			logger.error("Modify host fail:", e);
			return new BsmResult(false, "修改失败");
		} finally {
			if (null != lock) {
				lock.release();
			}
		}
	}

	@Override
	public BsmResult remove(Long id, Long userId) {
		String path = HostSystem.class.getSimpleName() + "_" + id;
		HarmonyLock lock = null;
		try {
			lock = lockFactory.getLock(path);
			if (!lock.acquire(path, 10, TimeUnit.SECONDS)) {
				logger.warn("Get harmonyLock time out!");
				return new BsmResult(false, "请求超时");
			}
			HostSystem hostSystem = hostSystemDao.query(id);
			if (null == hostSystem) {
				return new BsmResult(false, "宿主机不存在");
			}
			if (null != hostSystem.getClusterId() && !hostSystem.isMaintain() && hostSystem.isConnected()) {
				return new BsmResult(false, "存在于集群中的宿主机必须进入维护模式才能删除");
			}
			CloudVendor vendor = cloudVendorDao.query(hostSystem.getVendorId());
			if (null == vendor) {
				return new BsmResult(false, "获取运供应商失败");
			}
			new Thread(new Runnable() {
				@Override
				public void run() {
					// 移除宿主机
					HostOperateModel model = new HostOperateModel();
					model.setHostName(hostSystem.getName());
					model.setClusterName(hostSystem.getClusterName());
					BsmResult result = hostProvider.remove(vendor.getUuid(), null, model);
					String type = vendor.getType();
					String operate = type.toLowerCase() + ".host";
					if (result.isSuccess()) {
						try {
							List<CloudServer> servers = cloudServerDao.listByHid(id);
							for (CloudServer server : servers) {
								// 删除虚拟机下的快照
								snapshotDao.removeByVm(server.getId(), userId);
								storeHostDao.deleteByHost(server.getId(), "VM");
								networkHostDao.deleteByHost(server.getId(), "VM");
								networkCardDao.deleteByHost(server.getId(), "VM", userId);
							}
							// 删除虚拟机
							cloudServerDao.removeByHost(id, userId);
							storeHostDao.deleteByHost(id, "PM");
							networkHostDao.deleteByHost(id, "PM");
							networkCardDao.deleteByHost(id, "PM", userId);
							hostSystemDao.remove(id, userId);
						} catch (Exception e) {
							logger.error("删除失败", e);
							resourceEventPublisher.send(new OperateResult(false, "删除宿主机失败", operate,
									MapTools.simpleMap("vendorId", vendor.getId())));
						}
					}
					resourceEventPublisher.send(new OperateResult(result.isSuccess(), result.getMessage(), operate,
							MapTools.simpleMap("vendorId", vendor.getId())));
				}
			}).start();
			return new BsmResult(true, "删除任务已下发，正在执行...");
		} catch (Exception e) {
			logger.error("Remove host error:", e);
			return new BsmResult(false, "删除失败");
		} finally {
			if (null != lock) {
				lock.release();
			}
		}
	}

	@Override
	public BsmResult detail(Long id) {
		try {
			HostSystem host = this.hostSystemDao.query(id);
			if (null == host) {
				return new BsmResult(false, "数据不存在");
			}
			host.setNetcards(networkCardDao.listByHost(host.getId(), "PM"));
			List<Param> params = Lists.newArrayList();
			params.add(new Param(MapTools.simpleMap("hostId", host.getId()), Sign.EQ));
			int vmNum = cloudServerDao.count(params);
			params.add(new Param(MapTools.simpleMap("isTemplate", 1), Sign.EQ));
			int templateNum = cloudServerDao.count(params);
			host.setVmNum(vmNum - templateNum);
			host.setTemplateNum(templateNum);
			return new BsmResult(true, host, "查询详情成功");
		} catch (Exception e) {
			logger.error("Get host error：", e);
			return new BsmResult(false, "查询详情失败");
		}
	}

	@Override
	public BsmResult createVSwitch(SwitchModel switchModel, Long userId) {
		try {
			CloudVendor cloudVendor = cloudVendorDao.query(switchModel.getVendorId());
			if (null == cloudVendor) {
				logger.error("get cloudVendor and region failure");
				return new BsmResult(false, "未获取到云供应商");
			}
			Map<Long, List<Long>> hosts = switchModel.getHosts();
			Map<String, List<String>> values = Maps.newHashMap();
			List<NetworkCard> networkCards = Lists.newArrayList();
			// 获取宿主机名称和网卡名称
			for (Long hostId : hosts.keySet()) {
				List<Long> cardIds = hosts.get(hostId);
				List<String> cards = Lists.newArrayList();
				for (Long cardId : cardIds) {
					NetworkCard card = this.networkCardDao.query(cardId);
					cards.add(card.getName());
					networkCards.add(card);
				}
				HostSystem host = this.hostSystemDao.query(hostId);
				values.put(host.getName(), cards);
			}
			switchModel.setValues(values);
			// 取得数据中心名称，放入SwitchModel中
			Long vdcId = switchModel.getVdcId();
			Vdc vdc = vdcDao.query(vdcId);
			switchModel.setVdcName(vdc.getName());
			// 创建交换机
			BsmResult result = networkProvider.createVSwitch(cloudVendor.getUuid(), switchModel);
			// 创建成功则更新网卡为已使用
			if (result.isSuccess()) {
				for (NetworkCard card : networkCards) {
					card.setUsed(true);
					card.setMenderId(userId);
					networkCardDao.update(card);
				}
				List<Network> networks = this.networkDao.listByVdc(vdcId);
				Map<String, Network> maps = Maps.newHashMap();
				for (Network network : networks) {
					maps.put(network.getNetworkVal(), network);
				}
				// 同步数据中心
				String content = JSONObject.toJSONString(result.getData());
				List<Network> nets = JSONObject.parseArray(content, Network.class);
				for (Network network : nets) {
					if (!maps.containsKey(network.getNetworkVal())) {
						network.setVendorId(switchModel.getVendorId());
						network.setCreaterId(userId);
						network.setMenderId(userId);
						network.setVdcId(vdcId);
						this.networkDao.save(network);
					}
				}
			}
			return new BsmResult(result.isSuccess(), result.getMessage());
		} catch (Exception e) {
			logger.error("exception info", e);
			return new BsmResult(false, "创建交换机失败");
		}
	}

	@Override
	public BsmResult listvmByvhost(long venderId, String hostName) {
		try {
			List<CloudServer> cloudServers = this.cloudServerDao.listvmByvhost(venderId, hostName);
			for (CloudServer cloudServer : cloudServers) {
				CloudVendor cloudVendor = cloudVendorDao.query(cloudServer.getVendorId());
				if (null != cloudVendor) {
					cloudServer.setVendorName(cloudVendor.getName());
				}
			}
			return new BsmResult(true, cloudServers, "查询成功");
		} catch (Exception e) {
			logger.error("exception info", e);
			return new BsmResult(false, "查询虚拟机失败");
		}
	}

	@Override
	public BsmResult getPerformance(String params) {
		// 获取所有的
		JSONObject object = JSONTools.isJSONObj(params);
		Long vendorId = object.getLong("vendorId");
		String name = object.getString("name");// 名称
		String type = object.getString("type");// 类型
		String time = object.getString("time");// 时间间隔
		try {
			CloudVendor vendor = this.cloudVendorDao.query(vendorId);
			if (null == vendor) {
				logger.warn("CloudVendor does not exist!");
				return new BsmResult(false, "供应商不存在");
			}
			if (VendorType.OPENSTACK.toString().equals(vendor.getType())) {
				MonitorConvert monitorConvert = new MonitorConvert();
				return new BsmResult(true, monitorConvert.convertList(perfDao.listbytype(vendor.getId(), name), type),
						"success");
			}

			BsmResult result = monitorProvider.query(vendor.getUuid(), name, "HostSystem", type, time);
			if (result.isSuccess()) {
				if (type.equals("DISK")) {
					return result;
				} else {
					MonitorModel model = JSONObject.parseObject(JSONObject.toJSONString(result.getData()),
							MonitorModel.class);
					List<MonitorCategoryModel> monitors = model.getValues();
					List<MonitorCategoryModel> values = Lists.newArrayList();
					for (MonitorCategoryModel monitor : monitors) {
						List<String> oldDatas = monitor.getData();
						List<String> newDatas = Lists.newArrayList();
						for (String data : oldDatas) {
							newDatas.add(new BigDecimal(Float.valueOf(data))
									.divide(new BigDecimal(100), 2, RoundingMode.HALF_UP).toString());
						}
						values.add(new MonitorCategoryModel(monitor.getName(), newDatas));
					}

					MonitorModel monitorModel = new MonitorModel(model.getKeys(), values);
					return new BsmResult(result.isSuccess(), monitorModel, result.getMessage());
				}
			}
			return result;
		} catch (Exception e) {
			logger.error("查询数据失败", e);
			return new BsmResult(false, "查询失败");
		}
	}

	@Override
	public BsmResult disconn(Long id, Long userId) {
		String path = HostSystem.class.getSimpleName() + "_" + id;
		HarmonyLock lock = null;
		try {
			lock = lockFactory.getLock(path);
			if (!lock.acquire(path, 10, TimeUnit.SECONDS)) {
				logger.warn("Get harmonyLock time out!");
				return new BsmResult(false, "请求超时");
			}
			HostSystem hostSystem = hostSystemDao.query(id);
			if (null == hostSystem) {
				return new BsmResult(false, "宿主机不存在");
			}
			CloudVendor vendor = cloudVendorDao.query(hostSystem.getVendorId());
			if (null == vendor) {
				return new BsmResult(false, "获取运供应商失败");
			}
			HostOperateModel model = new HostOperateModel();
			model.setHostName(hostSystem.getName());
			BsmResult result = hostProvider.disconn(vendor.getUuid(), null, model);
			if (result.isSuccess()) {
				hostSystem.setConnected(false);
				hostSystem.setMenderId(userId);
				hostSystem.setPowerState("UNKNOWN");
				hostSystem.setStatus("UNKNOWN");
				this.hostSystemDao.update(hostSystem);
				// 宿主机断开连接，更新虚拟机状态
				this.cloudServerDao.updateStatusByHost(id, "UNKNOWNON", userId, VMStatus.RUNNING.name());
				this.cloudServerDao.updateStatusByHost(id, "UNKNOWNOFF", userId, VMStatus.STOPPED.name());
				this.cloudServerDao.updateStatusByHost(id, "UNKNOWNSUSPEND", userId, VMStatus.SUSPENDED.name());
			}
			return result;
		} catch (Exception e) {
			logger.error("disconnect host error:", e);
			return new BsmResult(false, "断开连接失败");
		} finally {
			if (null != lock) {
				lock.release();
			}
		}
	}

	@Override
	public BsmResult reconn(Long id, Long userId) {
		String path = HostSystem.class.getSimpleName() + "_" + id;
		HarmonyLock lock = null;
		try {
			lock = lockFactory.getLock(path);
			if (!lock.acquire(path, 10, TimeUnit.SECONDS)) {
				logger.warn("Get harmonyLock time out!");
				return new BsmResult(false, "请求超时");
			}
			HostSystem hostSystem = hostSystemDao.query(id);
			if (null == hostSystem) {
				return new BsmResult(false, "宿主机不存在");
			}
			CloudVendor vendor = cloudVendorDao.query(hostSystem.getVendorId());
			if (null == vendor) {
				return new BsmResult(false, "获取运供应商失败");
			}
			// 启动一个线程
			new Thread(new Runnable() {
				@Override
				public void run() {
					HostOperateModel model = new HostOperateModel();
					model.setHostName(hostSystem.getName());
					BsmResult result = hostProvider.reconn(vendor.getUuid(), null, model);
					String type = vendor.getType();
					String operate = type.toLowerCase() + ".host";
					try {
						if (result.isSuccess()) {
							hostSystem.setConnected(true);
							hostSystem.setMenderId(userId);
							hostSystem.setPowerState("RUNNING");
							hostSystem.setStatus("RUNNING");
							hostSystemDao.update(hostSystem);
							Long vendorId = vendor.getId();
							// 宿主机和网络的关系
							Map<String, Long> networkMap = Maps.newHashMap();
							Map<String, PortGroup> groupMap = Maps.newHashMap();
							List<Network> oldNetworks = networkDao.listByVdc(hostSystem.getVdcId());
							for (Network network : oldNetworks) {
								networkMap.put(network.getNetworkVal(), network.getId());
								List<PortGroup> groups = portGroupDao.listByNetwork(network.getId());
								for (PortGroup group : groups) {
									groupMap.put(group.getGroupVal(), group);
								}
							}
							// 宿主机连接，更新虚拟机状态
							List<CloudServer> oldServers = cloudServerDao.listByHid(id);
							Map<String, CloudServer> serverMap = Maps.newHashMap();
							for (CloudServer server : oldServers) {
								serverMap.put(server.getInstanceId(), server);
							}
							List<CloudServer> servers = JSONObject.parseArray(JSONObject.toJSONString(result.getData()),
									CloudServer.class);
							Map<String, Long> storeMap = new HashMap<>();
							List<DataStore> stores = dataStoreDao.listByVdc(hostSystem.getVdcId());
							for (DataStore store : stores) {
								storeMap.put(store.getStoreVal(), store.getId());
							}
							for (CloudServer cloudServer : servers) {
								if (serverMap.containsKey(cloudServer.getInstanceId())) {
									CloudServer server = serverMap.get(cloudServer.getInstanceId());
									String status = null;
									if (cloudServer.getStatus().equalsIgnoreCase("poweredOn")) {
										status = VMStatus.RUNNING.name();
									} else if (cloudServer.getStatus().equalsIgnoreCase("poweredOff")) {
										status = VMStatus.STOPPED.name();
									} else if (cloudServer.getStatus().equalsIgnoreCase("suspended")) {
										status = VMStatus.SUSPENDED.name();
									} else {
										status = VMStatus.EXCEPTION.name();
									}
									if (!status.equals(server.getStatus())) {
										server.setStatus(status);
										server.setMenderId(userId);
										server.setToolsInstalled(cloudServer.getToolsInstalled());
										server.setToolsRunning(cloudServer.getToolsRunning());
										cloudServerDao.update(server);
									}
									// 移除存在更新的虚拟机
									serverMap.remove(cloudServer.getInstanceId());
								} else {
									SyncVmwareUtils utils = new SyncVmwareUtils(cloudServerDao, dataStoreDao,
											hostSystemDao, snapshotDao, networkDao, null, storeHostDao, networkCardDao,
											portGroupDao, networkHostDao);
									utils.addServerCascade(storeMap, cloudServer, vendorId, id, userId,
											hostSystem.getPowerState(), networkMap, groupMap);
								}
							}
							Iterator<CloudServer> iterator = serverMap.values().iterator();
							while (iterator.hasNext()) {
								cloudServerDao.remove(iterator.next().getId(), userId);
							}
						}
						resourceEventPublisher.send(new OperateResult(result.isSuccess(), result.getMessage(), operate,
								MapTools.simpleMap("vendorId", vendor.getId())));
					} catch (Exception e) {
						logger.error("reconnect host error:", e);
						resourceEventPublisher.send(new OperateResult(false, "连接宿主机失败", operate,
								MapTools.simpleMap("vendorId", vendor.getId())));
					}
				}
			}).start();
			return new BsmResult(true, "连接任务已下发，正在执行...");
		} catch (Exception e) {
			logger.error("reconnect host error:", e);
			return new BsmResult(false, "连接失败");
		} finally {
			if (null != lock) {
				lock.release();
			}
		}
	}

	@Override
	public BsmResult entermaintain(Long id, Long userId) {
		String path = HostSystem.class.getSimpleName() + "_" + id;
		HarmonyLock lock = null;
		try {
			lock = lockFactory.getLock(path);
			if (!lock.acquire(path, 10, TimeUnit.SECONDS)) {
				logger.warn("Get harmonyLock time out!");
				return new BsmResult(false, "请求超时");
			}
			HostSystem hostSystem = hostSystemDao.query(id);
			if (null == hostSystem) {
				return new BsmResult(false, "宿主机不存在");
			}

			List<CloudServer> servers = cloudServerDao.listByHid(id);
			for (CloudServer server : servers) {
				if (!server.getStatus().equals(VMStatus.STOPPED.name())) {
					return new BsmResult(false, "宿主机下存在未关闭的虚拟机，无法进入维护模式，需人工关闭");
				}
			}

			CloudVendor vendor = cloudVendorDao.query(hostSystem.getVendorId());
			if (null == vendor) {
				return new BsmResult(false, "获取运供应商失败");
			}
			HostOperateModel model = new HostOperateModel();
			model.setHostName(hostSystem.getName());
			BsmResult result = hostProvider.enterMode(vendor.getUuid(), null, model);
			if (result.isSuccess()) {
				hostSystem.setMaintain(true);
				hostSystem.setMenderId(userId);
				this.hostSystemDao.update(hostSystem);
			}
			return result;
		} catch (Exception e) {
			logger.error("enter maintain error:", e);
			return new BsmResult(false, "进入维护模式失败");
		} finally {
			if (null != lock) {
				lock.release();
			}
		}
	}

	@Override
	public BsmResult exitmaintain(Long id, Long userId) {
		String path = HostSystem.class.getSimpleName() + "_" + id;
		HarmonyLock lock = null;
		try {
			lock = lockFactory.getLock(path);
			if (!lock.acquire(path, 10, TimeUnit.SECONDS)) {
				logger.warn("Get harmonyLock time out!");
				return new BsmResult(false, "请求超时");
			}
			HostSystem hostSystem = hostSystemDao.query(id);
			if (null == hostSystem) {
				return new BsmResult(false, "宿主机不存在");
			}
			CloudVendor vendor = cloudVendorDao.query(hostSystem.getVendorId());
			if (null == vendor) {
				return new BsmResult(false, "获取运供应商失败");
			}
			HostOperateModel model = new HostOperateModel();
			model.setHostName(hostSystem.getName());
			BsmResult result = hostProvider.exitMode(vendor.getUuid(), null, model);
			if (result.isSuccess()) {
				hostSystem.setMaintain(false);
				hostSystem.setMenderId(userId);
				this.hostSystemDao.update(hostSystem);
			}
			return result;
		} catch (Exception e) {
			logger.error("exit maintain error:", e);
			return new BsmResult(false, "退出维护模式失败");
		} finally {
			if (null != lock) {
				lock.release();
			}
		}
	}

	@Override
	public BsmResult move(HostOperateModel model, Long userId) {
		try {
			CloudVendor vendor = cloudVendorDao.query(model.getVendorId());
			if (null == vendor) {
				return new BsmResult(false, "获取运供应商失败");
			}
			HostSystem hostSystem = hostSystemDao.query(model.getHostId());
			if (null == hostSystem) {
				return new BsmResult(false, "宿主机不存在");
			}
			if (hostSystem.isConnected() && null != hostSystem.getClusterId() && !hostSystem.isMaintain()) {
				return new BsmResult(false, "宿主机不是维护模式且是连接状态，无法移动");
			}
			List<String> hosts = Lists.newArrayList();
			hosts.add(model.getHostName());
			model.setHosts(hosts);
			BsmResult result = hostProvider.moveTo(vendor.getUuid(), null, model);
			if (result.isSuccess()) {
				if (StringUtils.isEmpty(model.getClusterName())) {
					hostSystem.setClusterId(null);
				} else {
					hostSystem.setClusterId(model.getClusterId());
				}
				hostSystem.setMenderId(userId);
				hostSystemDao.update(hostSystem);
			}
			return result;
		} catch (Exception e) {
			logger.error("exit maintain error:", e);
			return new BsmResult(false, "移动主机失败");
		}
	}

}
